﻿using System;
using System.Web.Mvc;
using Peak.ApplicationServices.Services;
using Peak.Resources;
using MvcContrib;
using Peak.Web.Controllers.FormsAuthentication;
using Peak.Web.Controllers.Services;
using SharpArch.Web.NHibernate;
using Peak.Web.Controllers.Models;

namespace Peak.Web.Controllers
{
  public class AccountController : Controller
  {
    private readonly ISessionService _sessionService;
    private readonly IFormsAuthenticationService _formsAuthenticationService;
    private readonly IUserService _userService;

    public AccountController(ISessionService sessionService, IFormsAuthenticationService formsAuthenticationService, IUserService userService)      
    {
      _sessionService = sessionService;
      _formsAuthenticationService = formsAuthenticationService;
      _userService = userService;      
    }

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Login()
    {
      if (User.Identity.IsAuthenticated)
      {
        if (_sessionService.User == null)
        {
          _formsAuthenticationService.SignOut();
          return View();
        }
        return this.RedirectToAction<ProjectsController>(f => f.CheckDefault());
      }
      else
        return View();
    }



    [Transaction]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Login(LoginDataModel loginDataModel)
    {
      if (!loginDataModel.IsValid())
      {
        return View();
      }

      if (!_userService.ValidateUser(loginDataModel.UserName, loginDataModel.Password))
      {
        ModelState.AddModelError<LoginDataModel>(f => f.Password, ValidationErrors.InvalidUserNameOrPassword);
        return View();
      }

      _formsAuthenticationService.SignIn(loginDataModel.UserName, loginDataModel.RememberMe);
      if (!String.IsNullOrEmpty(loginDataModel.ReturnUrl))
      {
        return Redirect(loginDataModel.ReturnUrl);
      }

      return this.RedirectToAction<ProjectsController>(f => f.CheckDefault());
    }

    [Transaction]
    public ActionResult Logout()
    {
      Session.Abandon();
      _formsAuthenticationService.SignOut();

      return this.RedirectToAction(f => f.Login());
    }

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult CreateAccount()
    {
      return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    [Transaction]
    public ActionResult CreateAccount(CreateAccountModel user)
    {
      if(!user.IsValid())
      {
        return View(user);
      }      

      CreateUserStatus status = _userService.CreateUser(user.UserName, user.Password, user.Email);
      switch (status)
      {
        case CreateUserStatus.Success:
          _formsAuthenticationService.SignIn(user.UserName, false /* createPersistentCookie */);
          return this.RedirectToAction<ProjectsController>(f => f.Index()); 
        case CreateUserStatus.DuplicateUserName:
          ModelState.AddModelError<CreateAccountModel>(f=>f.UserName, CreateUserStatusMessages.DuplicateUserName);
          break;
        case CreateUserStatus.DuplicateEmail:
          ModelState.AddModelError<CreateAccountModel>(f => f.Email, CreateUserStatusMessages.DuplicateEmail);
          break;
        default:
          throw new ArgumentOutOfRangeException();
      }
      
      return View(user);
    }    
  }
}
